package lion.crawl;

import java.util.ArrayList;
import java.util.List;

import lion.crawl.fetch.HttpDownloader;
import lion.crawl.fetch.IDownloader;
import lion.crawl.parse.Page;
import lion.crawl.parse.ParseListener;
import lion.crawl.parse.URLRule;
import lion.crawl.rule.ParseRule;
import lion.crawl.url.RAMURLBase;
import lion.crawl.url.URLBase;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 
 * 抓取旅行
 * 
 * @author Helin*
 * 
 * @date 2012-8-16
 * @email hl_0074@sina.com
 */
public class Traveler {

	private static Log log = LogFactory.getLog(Traveler.class);

	private String name;// 旅行名称
	private String startPage; // 入口url 这是起点
	private URLBase urlBase;// url地址库
	private int level;// 抓取深度
	private List<URLRule> pageRules = new ArrayList<>(); // 行走路线
	private int threadNum = 1;// 线程数
	private List<ParseRule> parseRules = new ArrayList<>();// 抓取规则
	private ParseListener parseListener;
	private Crawler[] crawlers;
	private TravelMonitor travelMonitor;
	private IDownloader downloader;

	public void start() {

		travelMonitor = new TravelMonitor(this);

		if (this.urlBase == null) {
			this.urlBase = new RAMURLBase();
		}

		if (this.urlBase.size() == 0) {
			this.urlBase.add(new Page(this.startPage, 0));
		}

		crawlers = new Crawler[this.threadNum];
		for (int i = 0; i < this.threadNum; i++) {
			crawlers[i] = new Crawler(this);
			crawlers[i].setName("crawler-" + i);
		}

		for (Crawler crawler : crawlers) {
			crawler.start();
		}

		travelMonitor.start();
		log.debug(this.threadNum + " crawlers started");
	}

	public void stop() {

		if (crawlers != null) {
			for (Crawler crawler : crawlers) {
				crawler.exit();
			}
			for (Crawler crawler : crawlers) {
				try {
					crawler.join();
				} catch (InterruptedException e) {
				}
			}
		}
		try {
			travelMonitor.exit();
			travelMonitor.join();
		} catch (InterruptedException e) {
		}

		log.debug("all crawlers stoped");
	}

	public String getName() {

		return name;
	}

	public void setName(String name) {

		this.name = name;
	}

	public String getStartPage() {

		return startPage;
	}

	public void setStartPage(String startPoint) {

		this.startPage = startPoint;
	}

	public int getLevel() {

		return level;
	}

	public void setLevel(int level) {

		this.level = level;
	}

	public int getThreadNum() {

		return threadNum;
	}

	public void setThreadNum(int threadNum) {

		this.threadNum = threadNum;
	}

	public List<ParseRule> getParseRules() {

		return parseRules;
	}

	public void setParseRules(List<ParseRule> parseRules) {

		this.parseRules = parseRules;
	}

	public URLBase getUrlBase() {

		return urlBase;
	}

	public void setUrlBase(URLBase urlBase) {

		this.urlBase = urlBase;
	}

	public ParseListener getParseListener() {

		return parseListener;
	}

	public void setParseListener(ParseListener parseListener) {

		this.parseListener = parseListener;
	}

	public List<URLRule> getPageRules() {

		return pageRules;
	}

	public void setPageRules(List<URLRule> pageRules) {

		this.pageRules = pageRules;
	}

	public Crawler[] getCrawlers() {

		return crawlers;
	}

	public IDownloader getDownloader() {

		if (this.downloader == null) {
			this.downloader = new HttpDownloader();
		}

		return this.downloader;
	}

	public void setDownloader(IDownloader downloader) {

		this.downloader = downloader;
	}

}
